package huanghui.netstorage.dao;

import huanghui.netstorage.modle.EntryFile;
import huanghui.netstorage.modle.VirtualFile;
import huanghui.netstorage.util.NetStorage;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;

/**
 * A data access object (DAO) providing persistence and search support for
 * Virtualfile entities. Transaction control of the save(), update() and
 * delete() operations can directly support Spring container-managed
 * transactions or they can be augmented to handle user-managed Spring
 * transactions. Each of these methods provides additional information for how
 * to configure it for the desired type of transaction control.
 * 
 * @see huanghui.netstorage.modle.VirtualFile
 * @author MyEclipse Persistence Tools
 */

public class VirtualFileDAO extends BaseHibernateDAO {
	private static final Log log = LogFactory.getLog(VirtualFileDAO.class);
	// property constants
	public static final String MD5 = "md5";
	public static final String NAME = "name";
	public static final String TYPE = "type";
	public static final String PATH = "path";
	public static final String SIZE = "size";
	public static final String MODIFY_TIME = "modifyTime";

	public int save(VirtualFile transientInstance) {
		int result = NetStorage.ACK_FAIL;
		log.debug("saving Virtualfile instance");
		try {
			Integer id = (Integer) getSession().save(transientInstance);
			log.debug("save successful");
			result = NetStorage.ACK_OK;
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
		return result;
	}

	public int delete(int vfid) {
		log.debug("deleting VirtualFile instance");
	/*	Session session = getSession();
		session.beginTransaction();
		try {
			session.delete(persistentInstance);
			session.getTransaction().commit();
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}*/
		
		String sql = "delete from virtualfile  where id="+vfid;
		System.out.println("delete virtual File sql:"+sql);
		Session session = getSession();
		Transaction trans = session.beginTransaction();
		trans.begin();
		SQLQuery sQLQuery=session.createSQLQuery(sql);
		
		 sQLQuery.executeUpdate(); 
		 trans.commit();
		 return 0;
		
		
	}

	public VirtualFile findById(java.lang.Integer id) {
		log.debug("getting VirtualFile instance with id: " + id);
		try {
			VirtualFile instance = (VirtualFile) getSession().get(
					"huanghui.netstorage.modle.VirtualFile", id);
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	public List findByExample(VirtualFile instance) {
		log.debug("finding VirtualFile instance by example");
		try {
			List results = getSession().createCriteria(
					"huanghui.netstorage.modle.VirtualFile").add(
					Example.create(instance)).list();
			log.debug("find by example successful, result size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	public List findByProperty(String propertyName, Object value) {
		log.debug("finding VirtualFile instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from VirtualFile as model where model."
					+ propertyName + "= ?";
			Query queryObject = getSession().createQuery(queryString);
			queryObject.setParameter(0, value);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}
	
	
	public List excuteSql(String sql)
	{
		//Session session = getSession();
		SQLQuery query = getSession().createSQLQuery(sql);
		//query.setMaxResults(1);  
		List resultDate = query.list(); 
		return resultDate;

	}
	
	
	public int modifyFileName(int fid, String fname)
	{
		String sql = "update virtualfile set name = '"+fname+"'  where id="+fid;
		Session session = getSession();
		Transaction trans = session.beginTransaction();
		trans.begin();
		SQLQuery sQLQuery=session.createSQLQuery(sql);
		int result = sQLQuery.executeUpdate(); 
		trans.commit();
		return result;
	}
	
	public EntryFile findEntryFileById(int id)
	{
		EntryFile entryFile = null;
		String sql = "select entryFileId from virtualfile where id="+id;
		List list = excuteSql(sql);
		if (list != null && list.size() == 1)
		{
			entryFile = new EntryfileDAO().findById((Integer)list.get(0));
		}
		return entryFile;
	}
	
	public List<VirtualFile> findChildFile(int pid)
	{
		String sql = "select * from virtualfile where parentid="+pid;
		List list = excuteSql(sql);
		List<VirtualFile> vList = null;
		if (list != null && !list.isEmpty()) 
		{
			vList = new ArrayList<VirtualFile>();
			int len = list.size();
			for (int i = 0; i < len; i++) 
			{
				Object[] objects = (Object[]) list.get(i);
				VirtualFile vFile = new VirtualFile();
//				for (Object object : objects) 
//				{
					vFile.setId((Integer)objects[0]);
					vFile.setName((String) objects[3]);
					vFile.setType((Integer) objects[4]);
					BigInteger size = (BigInteger) objects[6];
					if(size != null)
					{
						vFile.setSize(size.longValue());
					}
					else
					{
						vFile.setSize(0l);
					}
					
					BigInteger modifyTime = (BigInteger) objects[7];
					vFile.setModifyTime(modifyTime.longValue());
					vList.add(vFile);
//				}
			}
		}
			
		return vList;
	}
	
	
	public Integer findRootId(int userId)
	{
		String sql = "select id from virtualfile where path='/' and userId="+userId;
		SQLQuery query = getSession().createSQLQuery(sql);
		return (Integer) query.uniqueResult();
	}
	
	public VirtualFile findVirtualFileByPidAndFilename(int pid, String fileName)
 {
		String sql = "select * from virtualfile where name='" + fileName
				+ "' and parentid=" + pid;
		List list = excuteSql(sql);
		VirtualFile vFile = null;
		if (list != null && list.size() == 1)
		{

			Object[] objects = (Object[]) list.get(0);
			vFile = new VirtualFile();
			vFile.setId((Integer) objects[0]);
			vFile.setName((String) objects[3]);
			vFile.setType((Integer) objects[4]);
			BigInteger size = (BigInteger) objects[6];
			if (size != null)
			{
				vFile.setSize(size.longValue());
			} 
			else 
			{
				vFile.setSize(0l);
			}

			BigInteger modifyTime = (BigInteger) objects[7];
			vFile.setModifyTime(modifyTime.longValue());
		}
		return vFile;
	}

	public List findByMd5(Object md5) {
		return findByProperty(MD5, md5);
	}

	public List findByName(Object name) {
		return findByProperty(NAME, name);
	}

	public List findByType(Object type) {
		return findByProperty(TYPE, type);
	}

	public List findByPath(Object path) {
		return findByProperty(PATH, path);
	}

	public List findBySize(Object size) {
		return findByProperty(SIZE, size);
	}

	public List findByModifyTime(Object modifyTime) {
		return findByProperty(MODIFY_TIME, modifyTime);
	}

	public List findAll() {
		log.debug("finding all VirtualFile instances");
		try {
			String queryString = "from VirtualFile";
			Query queryObject = getSession().createQuery(queryString);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

	public VirtualFile merge(VirtualFile detachedInstance) {
		log.debug("merging VirtualFile instance");
		try {
			VirtualFile result = (VirtualFile) getSession().merge(
					detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public void attachDirty(VirtualFile instance) {
		log.debug("attaching dirty VirtualFile instance");
		try {
			getSession().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void attachClean(VirtualFile instance) {
		log.debug("attaching clean VirtualFile instance");
		try {
			getSession().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}
}